package uia.alumni.data;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * An entity class to represent the group functunality of the project
 * Group's is a membership thing. It can represent for example the
 * class of '99. Each group will have access to it's own discussion board
 * where they'll be able to communicate with eachother.
 *
 * A user might join as many groups as he or she wish. So it's a ManyToMany
 * relationship to the user. To follow Relational DB this is done through a
 * extra table called group_participation. Each group will also have a
 * admin. This is done with roles. So we reuse the roles enum class in this
 * Context.
 *
 * v1 @ Thu Oct 29th.
 *
 * @author Simon Zimmermann
 */

@Entity @Table(name="is202_alumni_group")
@NamedQuery(
        name="Group.findAll",
        query="SELECT g FROM Group g ORDER BY g.name"
    )
public class Group {
    @Id @GeneratedValue @Column(name="group_id")
    private long id;

    @Column(name="group_name", unique=true, nullable=false)
    private String name;

    @Column(name="group_info")
    private String info;

    @OneToMany(mappedBy = "group", cascade = CascadeType.ALL, targetEntity = GroupParticipation.class)
    private List<GroupParticipation> memberList;

 
   @ManyToOne(optional=false)
        @JoinColumn(name="GROUPOWNER", referencedColumnName="user_id")
    private User gOwner;


    public Group(){
        this(null, null);
    }

    public Group(String name, User gOwner){
        this.name = name;
        this.gOwner = gOwner;
    }

    // Methods
    /**
     * This this work?
     * This seems to work ok.
     *
     * Not done much testing, yet though.
     *
     * User joins a group.
     * @param group
     * @param role
     */
    public void joinGroup(User user, Role role){
        GroupParticipation gp = new GroupParticipation(user, this, role);
        user.addGroup(gp);
        this.addMember(gp);
    }

    /**
     * Leave a group. Return true on success.
     * @param group
     * @return
     */
    public boolean leaveGroup(User user){
        Iterator<GroupParticipation> it = getMemberList().iterator();
        while(it.hasNext()){
            GroupParticipation gp = it.next();
            if(gp.getUser().equals(user)){
                it.remove();
               /**/
                return true;
            }
        }
        return false;
    }
    /**
     * Return an ArrayList of Users rather then GroupParticipation object.
     * @return ArrayList<User>
     */
    public ArrayList<User> getMembers(){
        ArrayList<User> members = new ArrayList<User>();
        for(GroupParticipation gp : getMemberList()){
            members.add(gp.getUser());
        }
        return members;
    }
    public void addMember(GroupParticipation gp){
        getMemberList().add(gp);
    }
    // Getters & Setters.
    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public List<GroupParticipation> getMemberList() {
        return memberList;
    }

    public User getOwner(){
        return gOwner;
    }
 }